package bid

import (
	"encoding/json"
	"errors"
	"strconv"
	"strings"
	"time"
	"wx-api/adx-bid/models/bid/BidModel"
	"wx-api/adx-bid/models/dsp/360ad/Ad360Model"
)

type M360AD struct {
}

func (z M360AD) DecodeReq(body []byte, cty string) (*BidModel.BidRequest, interface{}, string, error) {
	mm := &Ad360Model.BidRequest{}
	hty := "json"
	err := json.Unmarshal(body, mm)
	m := &BidModel.BidRequest{
		Id: mm.GetRequestId(),
	}
	if len(mm.GetImps()) == 0 {
		return nil, mm, "", errors.New("imp is empty")
	}
	if mm.GetApp() == nil {
		return nil, mm, "", errors.New("app is empty")
	}
	if mm.GetDevice() == nil {
		return nil, mm, "", errors.New("device is empty")
	}
	id := mm.GetRequestId()
	mediaid := string(id[0:5])
	tagid := string(id[5:12])
	d := mm.GetDevice()
	m.Device = &BidModel.BidRequest_Device{
		ConnectionType: func(a int32) string {
			if a == 5 {
				return "5g"
			} else if a == 4 {
				return "4g"
			} else if a == 3 || a == 2 {
				return "3g"
			}
			return "wifi"
		}(d.GetNetwork()),
		DeviceType:   "phone",
		Imei:         d.GetImei(),
		ImeiMd5:      d.GetImeiMd5(),
		Idfa:         d.GetIdfa(),
		IdfaMd5:      d.GetIdfaMd5(),
		AndroidId:    d.GetAndroidId(),
		AndroidIdMd5: d.GetAndroidIdMd5(),
		Oaid:         d.GetOaid(),
		OaidMd5:      d.GetOaidMd5(),
		Mac:          d.GetMac(),
		MacMd5:       d.GetMacMd5(),
		Ip:           d.GetIp(),
		Ua:           d.GetUserAgent(),
		Caids: func(i *Ad360Model.BidRequest_Device_Caid) []*BidModel.BidRequest_Device_Caid {
			if i == nil {
				return nil
			}
			ret := []*BidModel.BidRequest_Device_Caid{}
			if i.GetCaid() == "" && i.GetCaidMd5() == "" {
				return nil
			}
			if i.GetCaidVersion() == "" {
				return nil
			}
			ret = append(ret, &BidModel.BidRequest_Device_Caid{
				Caid:        i.GetCaid(),
				CaidMd5:     i.GetCaidMd5(),
				CaidVersion: i.GetCaidVersion(),
			})
			if len(ret) > 0 {
				return ret
			}
			return nil
		}(d.GetCaids()),
		Paid: d.GetPaid(),
		Brand: func(a, b string) string {
			if a != "" {
				return a
			}
			return b
		}(d.GetBrand(), d.GetModel()),
		Model: d.GetModel(),
		Os: func(a string) string {
			if strings.ToLower(a) == "ios" {
				return "ios"
			}
			return "android"
		}(d.GetOs()),
		Osv: d.GetOsVersion(),
		Carrier: func(a int32) string {
			if a == 2 {
				return "70123"
			} else if a == 3 {
				return "70121"
			}
			return "70120"
		}(d.GetCarrier()),
		Geo: func(a *Ad360Model.BidRequest_Device_Geo) *BidModel.BidRequest_Geo {
			if a == nil {
				return nil
			}
			return &BidModel.BidRequest_Geo{
				Lat: a.GetLatitude(),
				Lon: a.GetLongitude(),
			}
		}(d.GetGeo()),
		Orientation:    d.GetOrientation(),
		W:              d.GetScreenWidth(),
		H:              d.GetScreenHeight(),
		BootMark:       d.GetBootMark(),
		UpdateMark:     d.GetUpdateMark(),
		VersionCodeHms: d.GetSyscoreVersion(),
		VersionCodeAg:  d.GetAppstoreVersion(),
	}
	app := mm.GetApp()
	m.App = &BidModel.BidRequest_App{
		Id:     mediaid,
		Name:   app.GetAppName(),
		Bundle: app.GetPkgName(),
		Ver:    app.GetVersion(),
	}
	imp := mm.GetImps()[0]
	mimp := &BidModel.BidRequest_Imp{
		Id:       strconv.Itoa(int(imp.GetId())),
		Bidfloor: int32(imp.GetBidfloor()),
		Tagid:    tagid,
		Secure:   1,
	}
	switch imp.GetAdType() {
	case 1, 2:
		tmp_str, _ := json.Marshal(imp.GetTemplates())
		mimp.Native = &BidModel.BidRequest_Imp_Native{
			Request: string(tmp_str),
			TMax:    imp.GetTitleMaxLen(),
			DMax:    imp.GetDescMaxLen(),
			W:       imp.GetWidth(),
			H:       imp.GetHeight(),
		}
		mimp.Sc = "1"
	case 3, 4:
		mimp.Banner = &BidModel.BidRequest_Imp_Banner{
			W: imp.GetWidth(),
			H: imp.GetHeight(),
		}
		mimp.Sc = "2"
		if imp.GetAdType() == 3 {
			mimp.Sc = "3"
		}
		if imp.GetAdType() == 4 {
			mimp.Sc = "6"
		}
	case 5, 6:
		vv := imp.GetVideo()
		mimp.Video = &BidModel.BidRequest_Imp_Video{
			W:     imp.GetWidth(),
			H:     imp.GetHeight(),
			Maxdu: vv.GetMaxDuration(),
			Mindu: vv.GetMinDuration(),
		}
		mimp.Sc = "4"
		if imp.GetAdType() == 6 {
			mimp.Sc = "9"
		}
	}

	m.Imp = append(m.Imp, mimp)
	return m, mm, hty, err
}

func (z M360AD) EncodeRes(req interface{}, res *BidModel.BidResponse, cty string) (interface{}, error) {
	mreq := req.(*Ad360Model.BidRequest)
	mres := &Ad360Model.BidResponse{
		Code:    -1,
		Message: "no ad",
		Data:    nil,
	}
	if len(res.GetSeatbid()) == 0 {
		return mres, nil
	}
	if len(res.GetSeatbid()[0].GetBid()) == 0 {
		return mres, nil
	}
	bid := res.GetSeatbid()[0].GetBid()[0]
	data_group_ads := &Ad360Model.BidResponse_Data_Group_Ad{
		Id:              1,
		Price:           bid.GetPrice(),
		CreativeId:      bid.GetCrid(),
		Title:           bid.GetTitle(),
		Desc:            bid.GetDesc(),
		Link:            bid.GetClickUrl(),
		ClickTrackUrls:  bid.GetClicks(),
		ImpTrackUrls:    bid.GetViews(),
		AdWidth:         bid.GetW(),
		AdHeight:        bid.GetH(),
		InteractionType: 14,
		DownloadAd: func(a string) int32 {
			if a != "" {
				return 1
			}
			return 0
		}(bid.GetDownUrl()),
		Source:       bid.GetSource(),
		NativeAdType: 9,
	}
	if mreq.GetImps()[0].GetAdType() == 1 {
		data_group_ads.NativeAdType = 2
		if len(bid.GetImgs()) > 1 {
			data_group_ads.NativeAdType = 3
		}
	}
	if len(bid.GetImgs()) > 0 {
		for _, image := range bid.GetImgs() {
			data_group_ads.Imgs = append(data_group_ads.Imgs, &Ad360Model.BidResponse_Data_Group_Ad_Image{
				Url:    image.GetUrl(),
				Width:  image.GetW(),
				Height: image.GetH(),
				Desc:   image.GetDesc(),
			})
		}
	}
	if bid.GetApp() != nil {
		data_group_ads.AppInfo = &Ad360Model.BidResponse_Data_Group_Ad_App{
			PkgName:        bid.GetApp().GetPkg(),
			Name:           bid.GetApp().GetName(),
			LogoUrl:        bid.GetApp().GetIcon(),
			DownUrl:        bid.GetDownUrl(),
			SoftCorpName:   bid.GetApp().GetDev(),
			SensitiveUrl:   bid.GetApp().GetPri(),
			UsesPermission: bid.GetApp().GetPer(),
			Version:        bid.GetApp().GetVer(),
			Size:           int64(bid.GetApp().GetSize()),
			Intro:          bid.GetApp().GetFurl(),
			DsUrls:         bid.GetStartDown(),
			DfUrls:         bid.GetEndDown(),
			SsUrls:         bid.GetStartInstall(),
			SfUrls:         bid.GetEndInstall(),
			DeepLink:       bid.GetDpurl(),
			EventTracks:    []*Ad360Model.BidResponse_Data_Group_Ad_EventTrack{},
		}
		if len(bid.GetDplinksFalid()) > 0 {
			data_group_ads.AppInfo.EventTracks = append(data_group_ads.AppInfo.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      13,
				EventTrackUrls: bid.GetDplinksFalid(),
			})
		}
		if len(bid.GetDplinksSuccess()) > 0 {
			data_group_ads.AppInfo.EventTracks = append(data_group_ads.AppInfo.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      14,
				EventTrackUrls: bid.GetDplinksSuccess(),
			})
		}
	}
	if bid.GetVideo() != nil {
		v := bid.GetVideo()
		data_group_ads.Video = &Ad360Model.BidResponse_Data_Group_Ad_Video{
			Duration:    v.GetDuration() * 1000,
			MimeType:    1,
			Width:       v.GetW(),
			Height:      v.GetH(),
			VideoUrl:    v.GetUrl(),
			CoverUrl:    v.GetCimg().GetUrl(),
			Length:      v.GetSize(),
			EventTracks: []*Ad360Model.BidResponse_Data_Group_Ad_EventTrack{},
		}
		if len(v.GetExt().GetStart()) > 0 {
			data_group_ads.Video.EventTracks = append(data_group_ads.Video.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      1,
				EventTrackUrls: v.GetExt().GetStart(),
			})
		}
		if len(v.GetExt().GetFifteen()) > 0 {
			data_group_ads.Video.EventTracks = append(data_group_ads.Video.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      2,
				EventTrackUrls: v.GetExt().GetFifteen(),
			})
		}
		if len(v.GetExt().GetThirty()) > 0 {
			data_group_ads.Video.EventTracks = append(data_group_ads.Video.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      3,
				EventTrackUrls: v.GetExt().GetThirty(),
			})
		}
		if len(v.GetExt().GetFortyFive()) > 0 {
			data_group_ads.Video.EventTracks = append(data_group_ads.Video.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      4,
				EventTrackUrls: v.GetExt().GetFortyFive(),
			})
		}
		if len(v.GetExt().GetEnd()) > 0 {
			data_group_ads.Video.EventTracks = append(data_group_ads.Video.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      5,
				EventTrackUrls: v.GetExt().GetEnd(),
			})
		}
		if len(v.GetExt().GetMuteTracker()) > 0 {
			data_group_ads.Video.EventTracks = append(data_group_ads.Video.EventTracks, &Ad360Model.BidResponse_Data_Group_Ad_EventTrack{
				EventType:      6,
				EventTrackUrls: v.GetExt().GetMuteTracker(),
			})
		}
	}
	mimp := mreq.GetImps()[0]
	data_group := &Ad360Model.BidResponse_Data_Group{
		ImpId: mimp.GetId(),
	}
	data_group.Ads = append(data_group.Ads, data_group_ads)
	mres_data := &Ad360Model.BidResponse_Data{
		RequestId: res.GetId(),
		Ts:        time.Now().UnixNano() / 1e6,
	}
	mres_data.Groups = append(mres_data.Groups, data_group)
	mres.Data = mres_data
	mres.Code = 0
	mres.Message = "success"
	return mres, nil
}
